<template>
  <a-modal width="45vw" v-model:visible="showModal" @close="onClose" :title="title" class="modal-dialog-wrapper" unmount-on-close>
    <!-- 加载中 -->
    <a-spin style="width: 100%" :loading="loading" dot>
      <template #tip>
        <div style="font-size: 15px"
          >导入中...<br />
          关闭弹窗不影响导入进度，并支持在页面右上方查看状态
        </div>
      </template>
      <a-alert v-if="downloadImport == 'carUpdate'" style="margin-bottom: 20px">
        <template #title> 车辆更新导入须知： </template>
        <div style="color: #1d2129">
          1、车辆数据更新是以车牌号为维度，对此条车辆数据有内容的字段进行更新；
          <br />
          2、Excel中的字段为空时，系统将视为不进行更新；
          <br />
          3、若想将对应车辆的某个字段清空，可以在对应车辆的目标字段下输入
          <span style="color: #165dff">%清空% </span>
          <a-button type="primary" size="mini" @click="handleCopy('%清空%')">点击复制字符</a-button>
          ，导入成功后即可更新为空；
          <br />
          4、车牌号、车型、归属门店的字段无法进行清空；
        </div>
      </a-alert>
      <!-- 第一步 -->
      <template v-if="importStep == 1">
        <div class="block">
          <div class="label">1、下载导入模板</div>
          <div class="tip">请根据提示信息完善表格内容</div>
          <div v-if="downloadImport == 'carAssets'">
            <page-form-row>
              <page-form-item label="选择模板类型" required size="1">
                <a-select v-model="carAssetsTemplate" @change="carAssetsTemplateChange" placeholder="请选择" style="width: 200px">
                  <a-option value="carInsure">保险导入模板</a-option>
                  <a-option value="carInspection">年检导入模板</a-option>
                  <a-option value="carMaintenance">保养导入模板</a-option>
                </a-select>
              </page-form-item>
            </page-form-row>
            <a-button type="primary" v-if="carAssetsTemplate" @click="downloadTemp('import')"> 下载导入模版 </a-button>
          </div>
          <a-space v-else>
            <a-button type="primary" v-if="downloadImport" @click="downloadTemp('import')"> 下载导入模版 </a-button>
            <a-button type="primary" v-if="downloadUpdate" @click="downloadTemp('update')"> 下载更新模版 </a-button>
            <a-button type="primary" v-for="item in customDownloadList" @click="downloadTemp(item.key)" :key="item.key">
              {{ item.name }}
            </a-button>
          </a-space>
        </div>
        <div class="block" v-if="uploadAction">
          <div class="label">2、上传完善后的模版</div>
          <a-upload
            v-model:file-list="uploadValue"
            :action="uploadAction"
            :limit="1"
            :auto-upload="false"
            ref="uploadRef"
            accept=".xls,.xlsx"
            draggable
            with-credentials
            @success="uploadImportFn"
          >
            <!-- 上传按钮 -->
            <template #upload-button>
              <div class="upload-op-block">
                <div class="upload-icon"><icon-plus /></div>
                <a-space direction="vertical" :size="4" fill>
                  <div>点击或拖拽文件到此处上传</div>
                  <div class="sub-tip">将文件进行上传。支持格式：xls、xlsx</div>
                </a-space>
              </div>
            </template>
            <template #upload-item="{ fileItem }">
              <div class="upload-item-block">
                <img :src="excelIcon" width="32" />
                <div class="filename">{{ fileItem.name }} <icon-close-circle-fill size="20" class="close" @click="delItem" /> </div>
                <!-- <a-button type="outline" @click="delItem">重新上传</a-button> -->
              </div>
            </template>
          </a-upload>
        </div>
      </template>
      <!-- 第2步（结果） -->
      <a-result v-else :status="importRes.status" :title="importRes.title" :subtitle="importRes.content">
        <template #extra>
          <a-space>
            <a-button type="primary" v-if="importRes.status == 'warning'" @click="downloadFailRecord">下载导入失败信息</a-button>
          </a-space>
        </template>
      </a-result>
    </a-spin>
    <template #footer>
      <a-space>
        <a-button @click="onClose">关闭</a-button>
        <a-button v-if="importStep == 1" :loading="loading" type="primary" @click="toSubmit">
          {{ loading ? '导入中' : '确认' }}
        </a-button>
        <a-button v-if="importStep == 2" @click="toInitStep">继续导入</a-button>
      </a-space>
    </template>
  </a-modal>
</template>

<script lang="ts">
  import { defineComponent, ref } from 'vue'
  import { Message, Modal } from '@arco-design/web-vue'
  import { getImportResult, downloadFailFile } from '@/api/common/index.js'
  import {
    carListImportTemplate,
    carRepairImportTemplate,
    carMaintenanceImportTemplate,
    carInspectionImportTemplate,
    carInsuranceImportTemplate,
    shortOrderBillImportTemplate,
    carPurchaseImportTemplate,
    carPurchaseNotStagedImportTemplate,
    carUpdateTemplate,
  } from '@/api/common/importTemp.js'
  import { download } from '@/utils/download'
  import excelIcon from './icons/excel.png'
  import useClipboard from 'vue-clipboard3'

  // 需要通过api下载的模板配置
  const IMPORT_TEMP_APIS = {
    carList: {
      fetch: carListImportTemplate,
      fileName: '车辆导入模板.xlsx',
    },
    shortOrderBill: {
      fetch: shortOrderBillImportTemplate,
      fileName: '短租对账模板.xlsx',
    },
    carPurchase: {
      fetch: carPurchaseImportTemplate,
      fileName: '车辆购置费分期模板.xlsx',
    },
    carPurchaseNotStaged: {
      fetch: carPurchaseNotStagedImportTemplate,
      fileName: '车辆购置费不分期模板.xlsx',
    },
    carUpdate: {
      fetch: carUpdateTemplate,
      fileName: '批量更新车辆模板.xlsx',
    },
    // 车辆资产 before
    carInsure: {
      fetch: carInsuranceImportTemplate,
      fileName: '车辆保险导入模板.xlsx',
      action: '/carInsurance/importExcel',
    },
    carInspection: {
      fetch: carInspectionImportTemplate,
      fileName: '车辆年检导入模板.xlsx',
      action: '/inspection/importExcel',
    },
    carMaintenance: {
      fetch: carMaintenanceImportTemplate,
      fileName: '车辆保养导入模板.xlsx',
      action: '/carMaintenance/importExcel',
    },
    carRepair: {
      fetch: carRepairImportTemplate,
      fileName: '车辆维修导入模板.xlsx',
      action: '/repair/importExcel',
    },
    // 车辆资产导入，特殊需要选择模板类型
    carAssets: {
      select: true,
    },
    // 车辆资产 end
  }

  export default defineComponent({
    name: 'ImportModal',
    props: {
      title: {
        type: String,
        default: 'Excel导入',
      },
      // 上传url
      action: String,
      // 下载导入模板
      downloadImport: String,
      // 下载更新模板
      downloadUpdate: String,
      // 自定义下载模板
      customDownloadList: Array,
    },
    emits: ['ok', 'close'],
    setup(props, { emit, expose }) {
      const uploadAction = ref()
      // 上传url
      if (props.action) {
        uploadAction.value = import.meta.env.VITE_BASE_PATH + props.action
      }
      const uploadValue = ref([])
      const showModal = ref(false)
      const loading = ref(false)

      // 步骤 1未上传、2上传完成
      const importStep = ref(1)

      // 初始化上传，返回上传页面
      const toInitStep = () => {
        uploadValue.value.length = 0
        importStep.value = 1
      }
      // 关闭
      const onClose = () => {
        toInitStep()
        showModal.value = false
        emit('close')
        return Promise.resolve(false)
      }
      // 删除文件
      const delItem = () => {
        uploadValue.value.length = 0
      }
      // 下载模板
      const downloadTemp = (type: string) => {
        let downUrl
        if (props.customDownloadList) {
          downUrl = type
        } else if (carAssetsTemplate.value) {
          downUrl = carAssetsTemplate.value
        } else {
          downUrl = type == 'import' ? props.downloadImport : props.downloadUpdate
        }

        if (!downUrl) return
        if (downUrl in IMPORT_TEMP_APIS) {
          const importTemp = IMPORT_TEMP_APIS[downUrl as keyof typeof IMPORT_TEMP_APIS]
          Message.success('开始下载模板文件...')
          importTemp
            .fetch()
            .then((res: any) => {
              download(res, 'application/excel;charset=UTF-8', importTemp.fileName)
            })
            .catch(() => {
              Message.error('下载失败')
            })
          return
        }
        const baseUrl = import.meta.env.VITE_FILE_BASE_URL + '/svms/document'
        window.open(baseUrl + downUrl)
      }

      // 上传 before
      const importRes = ref({})
      const uploadRef = ref()
      let taskId = 0
      // 去上传&导入
      const toSubmit = () => {
        if (uploadValue.value.length == 0) {
          Message.warning('请先上传文件')
          return
        }
        if (props.downloadImport == 'carUpdate') {
          Modal.confirm({
            title: '提示',
            simple: true,
            cancelText: '取消',
            okText: '确认',
            bodyStyle: {
              'text-align': 'center',
            },
            content: '系统将会以excel表格中最新的内容，对原有字段的内容进行覆盖！请您再次确认。',
            onOk: () => {
              loading.value = true
              uploadRef.value.submit()
            },
          })
          return
        }
        loading.value = true
        uploadRef.value.submit()
      }
      // 【轮询3s】获取导入结果
      const getImportResFn = () => {
        getImportResult({ id: taskId })
          .then((res: any) => {
            const result = res.result
            // 关闭导入
            if (result.status != 1) {
              loading.value = false
            }
            // 进行中
            switch (result.status) {
              case 1: // 进行中
                setTimeout(() => {
                  getImportResFn()
                }, 3000)
                break
              case 2: // 成功
                importStep.value = 2
                if (result.errorCount > 0) {
                  importRes.value = {
                    status: 'warning',
                    title: '导入完成',
                    content: `共${result.totalCount}条，成功${result.successCount}条，失败${result.errorCount}条`,
                  }
                } else {
                  importRes.value = {
                    status: 'success',
                    title: '导入完成',
                    content: `成功${result.successCount}条`,
                  }
                }
                // 通知页面导出成功
                emit('ok', 1)
                break
              case 3: // 异常
                importStep.value = 2
                importRes.value = {
                  status: 'error',
                  title: '导入失败',
                  content: `系统服务异常，请稍后再试`,
                }
                break
              case 4: // 空
                importStep.value = 2
                importRes.value = {
                  status: 'error',
                  title: '导入失败',
                  content: `导入数据为空，请检查您的附件`,
                }
                break
              default:
                break
            }
          })
          .catch(() => {
            loading.value = false
            importStep.value = 2
            importRes.value = {
              status: 'error',
              title: '导入数据失败',
              content: `服务错误，请稍后再试`,
            }
          })
      }
      // 上传成功
      const uploadImportFn = (res: { response: { result: number } }) => {
        taskId = res.response.result
        setTimeout(() => {
          getImportResFn()
        }, 2000)
      }
      // 下载失败记录
      const downloadFailRecord = () => {
        downloadFailFile({ id: taskId })
      }
      // end

      const { toClipboard } = useClipboard()
      // 复制
      const handleCopy = async (text: string) => {
        try {
          await toClipboard(text)
          Message.success('复制成功')
        } catch (error) {
          Message.error('复制失败')
        }
      }

      // 打开导入弹框
      const show = () => {
        showModal.value = true
        return Promise.resolve(true)
      }

      const carAssetsTemplate = ref()
      const carAssetsTemplateChange = (val: any) => {
        if (!val) {
          uploadAction.value = undefined
          return
        }
        const importTemp = IMPORT_TEMP_APIS[val as keyof typeof IMPORT_TEMP_APIS]
        uploadAction.value = import.meta.env.VITE_BASE_PATH + importTemp.action
      }

      expose({
        show,
      })

      return {
        loading,
        uploadValue,
        excelIcon,
        showModal,
        uploadAction,
        importStep,
        importRes,
        uploadRef,
        carAssetsTemplate,
        carAssetsTemplateChange,
        show,
        onClose,
        toSubmit,
        delItem,
        downloadTemp,
        uploadImportFn,
        toInitStep,
        downloadFailRecord,
        handleCopy,
      }
    },
  })
</script>

<style lang="less" scoped>
  .block {
    margin-bottom: 20px;
    padding: 16px;
    background: rgba(247, 248, 250, 0.5);
    border-radius: 2px;
    border: 1px solid #e5e6eb;
    max-height: 222px;
    overflow: hidden;

    .label {
      margin-bottom: 8px;
      font-size: 14px;
      font-weight: 400;
      color: #1d2129;
      line-height: 20px;
    }

    .tip {
      margin-bottom: 16px;
      font-size: 14px;
      font-weight: 400;
      color: #86909c;
      line-height: 20px;
    }
  }

  .upload-op-block {
    height: 160px;
    width: 100%;
    background: #f2f3f5;
    border-radius: 2px 2px 2px 2px;
    border: 1px solid #e5e6eb;
    text-align: center;
    padding: 38px 0;
    font-size: 14px;
    line-height: 22px;
    color: #1d2129;
    .upload-icon {
      margin-bottom: 24px;
    }
    .sub-tip {
      margin-top: 4px;
      font-size: 12px;
      color: #86909c;
      line-height: 20px;
    }
  }
  .upload-item-block {
    height: 160px;
    width: 100%;
    padding-top: 32px;
    text-align: center;
    background: #f2f3f5;
    border-radius: 2px 2px 2px 2px;
    border: 1px solid #e5e6eb;

    font-size: 12px;
    font-weight: 400;
    color: #ffffff;
    line-height: 22px;

    .filename {
      margin-top: 2px;
      margin-bottom: 8px;
      font-size: 14px;
      color: #1d2129;
      line-height: 22px;
      display: flex;
      align-items: center;
      justify-content: center;
      .close {
        margin-left: 10px;
        color: red;
        cursor: pointer;
      }
    }
  }
</style>
